<!--
 * @Author: 秦福凯
 * @Date: 2024-07-23 18:39:46
 * @Description: 公共表单
 * @FilePath: \sx-school-oa\src\components\common\form\form.vue
-->
<template >
  <el-form v-if="refrashForm" v-bind="$attrs" :model="form" class="u-common-form" ref="soform" :rules="setRules" :disabled="props.isCheck">
    <el-row :gutter="12" class="f-w-100">
      <el-col v-for="(item,index) in element" :key="item.key" :span="item.sp || 8" >
        <el-form-item  :label="item.label" :label-width="item.lw || '88px'" :prop="item.key" v-show="item.isshow || true" :class="item.class">
          <!-- 输入框 -->
          <template v-if="item.type == 'input'">
            <u-input @focus="emits('Inputfocus',item.key,form[item.key])" :type="item.ctype" v-model="form[item.key]" v-bind="item" @change="changeForm(item.key,form[item.key])"></u-input>
          </template>

          <!-- 密码输入输入框 -->
          <template v-if="item.type == 'password'">
            <u-input @focus="emits('Inputfocus',item.key,form[item.key])" show-password type="password" v-model="form[item.key]" v-bind="item" @change="changeForm(item.key,form[item.key])"></u-input>
          </template>

          <!-- 文本域 -->
          <template v-if="item.type == 'textarea'">
            <u-input v-bind="item" :placeholder="item.placeholder || '请输入'" v-model="form[item.key]" type="textarea" :rows="4" @change="changeForm(item.key,form[item.key])"></u-input>
          </template>
          
          <!-- 数字输入框 金额输入框---precision -->
          <template v-else-if="item.type == 'numInput'">
            <el-input-number
              class="u-common-numInput"
              style="width: 100%; text-align: left;"
              @change="changeForm(item.key,form[item.key])"
              v-model="form[item.key]" v-bind="item"
              :controls="item.controls || false"
              :precision="item.ctype == 'money' ? 2 : 0">
          </el-input-number>
          </template>

          <!-- 验证码 -->
          <template v-else-if="item.type == 'yzm'">
            <div style="width: 100%;display: flex;justify-content:space-between;">
              <span style="width: calc(50% - 12px);margin-right: 12px;">
                <u-input @focus="emits('Inputfocus',item.key,form[item.key])"  v-model="form[item.key]" v-bind="item" @change="changeForm(item.key,form[item.key])"></u-input>
              </span>
              <span style="width: 50%;">
                <el-image :src="item.src" @click="getUuid" style="	margin-left: 10px;width: 140px;height: 40px;cursor: pointer;"> 
                  <template #error>
                    <div @click="getUuid" style="
                      box-sizing: border-box;
                      width: 100%;
                      height: 90%;
                      background-color: var(--el-fill-color-light);
                      border: solid 1px var(--el-border-color);
                      text-align: center;
                      color: var(--el-text-color-secondary);
                      border-radius: 4px;">
                      重新加载
                    </div>
                   </template>
               </el-image>
              </span>
            </div>
          </template>


          <!-- 下拉框 -->
          <template v-else-if="item.type == 'select'">
            <u-select :refrash="refrashSel" :data="item.data"  v-model="form[item.key]" v-bind="item"  @change="changeForm(item.key,form[item.key])"></u-select>
          </template>

          <!-- 自定义 -->
          <template v-else-if="item.type == 'slot'">
            <slot :name="item.key"></slot>
          </template>

          <!-- 单选框 -->
          <template v-else-if="item.type == 'radio'">
            <el-radio-group v-model="form[item.key]" v-bind="item" @change="changeForm(item.key,form[item.key])">
            <el-radio  v-for="citem in item.data" :value="item.isid == true ? citem.id : citem.value " :key="citem.value">
              {{ citem.label }}
            </el-radio>
          </el-radio-group>
          </template>

          <!-- 多选框 -->
          <template v-else-if="item.type == 'checkbox'">
            <el-checkbox-group v-model="form[item.key]" v-bind="item">
              <el-checkbox v-for="citem in item.data" :label="citem.label" :value="citem.value" />
            </el-checkbox-group>
          </template>

          <!-- 联级选择器 -->
          <template v-else-if="item.type == 'cascader'">
            <el-cascader
              style="width: 100%;"
              placeholder="请选择"
              v-model="form[item.key]"
              :clearable="true"
              v-bind="item"
              :options="item.options || []"
              :props="item.prop || {value:'label'}"
              ></el-cascader>
            </template>

           <!-- 树形选择 -->
           <template v-else-if="item.type == 'selectTree'">
            <el-tree-select v-model="form[item.key]" :data="item.data"  v-bind="item"/>
            </template>

          <!-- 时间选择框 -->
          <template v-else-if="item.type == 'date'">
            <el-date-picker
              v-bind="item"
              v-model="form[item.key]"
              :type="item.date || 'date'"
              :placeholder="item.placeholder || '请选择时间'"
              :format="item.format || 'YYYY-MM-DD'"
              :value-format="item.valueFormat || 'YYYY-MM-DD'"
              :picker-options="item.pickOptions || {}"
              @change="changeForm(item.key,form[item.key])"
            />
          </template>

          <!-- 文件上传 ---拖拽 -->
          <template v-else-if="item.type == 'upload'">
            <el-upload
              class="u-form-upload"
              action="#"
              :auto-upload="false"
              :on-change="fileUpload"
              :http-request="uploadHttpRequest"
              :show-file-list="item.showList == true ? true : false"
              :accept="item.accept"
              drag
              multiple>
              <el-icon class="el-icon--upload"><upload-filled /></el-icon>
              <div class="el-upload__text">
                {{item.fileName || fileName}}
              </div>
              <template #tip>
                <div class="el-upload__tip" v-if="item.showtext">
                  {{ item.showtext }}
                </div>
              </template>
            </el-upload>
          </template>

          <!-- 文件上传--按钮 -->
          <template v-else-if="item.type == 'fileBtn'" >
            <el-upload
               v-model:file-list="fileLists"
              ref="upload"
              action="#"
              :show-file-list="item.showList == false ? false : true"
              :auto-upload="false"
              :on-exceed="handleExceed"
              :on-remove="handleRemove"
              :before-remove="beforeRemove"
              :limit="1"
              :on-change="(file, fileList) => {fileUpload(file, fileList,index)}"
              >
            <div >
              <el-button class="upload-btn" slot="trigger" size="small" type="primary" >上传</el-button>
            </div>
        </el-upload>
          </template>

          <!-- 图片上传图片展示 -->
          <template v-else-if="item.type == 'uploadImg'" class="u-common-form-uploadImg">
            <el-upload
              style="height: 200px;width: 200px;display: flex;align-items: center;justify-content: center;border: 1px solid;"
              action="#"
              :show-file-list="false"
              :on-change="(file, fileList) => {fileUpload(file, fileList,index)}"
              :auto-upload="false"
              >
            <img v-if="form[item.key]" :src="form[item.key]" style="max-width: 200px;max-height:200px;overflow: hidden;" />
            <el-icon v-else  style="font-size: 50px;"><UploadFilled /></el-icon>
          </el-upload>
          </template>

          <!-- 文件选取和上传 -->
          <template v-else-if="item.type == 'setfile'">
            <el-upload
              v-model:file-list="fileLists"
              ref="upload2"
              action="#"
              :auto-upload="false"
              :on-exceed="handleExceed"
              :on-change="(file, fileList) => {fileUpload(file, fileList,index)}"
            >
          <el-button slot="trigger" size="small" type="primary">选取文件</el-button>
        </el-upload>
        <el-button v-if="item.showSer" @click="emits('submitUpload',item.key,form[item.key],index)"   style="position: absolute;top: 5px;left: 70px;" size="small" type="success" >上传到服务器</el-button>
          </template>

          <template v-else-if="item.type == 'span'">
            <span>{{form[item.key]}}</span>
          </template>

          <template v-else-if="item.type == 'dictspan'">
            <span>{{getDictLabel(item.dict, form[item.key],item.dictType) }}</span>
          </template>
        </el-form-item>
      </el-col>
    </el-row>

  </el-form>
</template>

<script setup>
import { ref, reactive,computed,} from 'vue'
import { genFileId } from 'element-plus'
// import {baseapi} from '@/api/baseapi.ts'
  let props = defineProps({
    element:Array,
    form:Object,
    fileLists:{
      type:Array,
      default:[]
    },
    isCheck:{
      type:Boolean,
      default:false
    }

  })
  const emits = defineEmits(['changeForm','fileUpload','handleRemove','remoteMethod','getUuid'])

  function changeForm(key,value){
    emits('changeForm',key,value)
  }

  function getUuid(){
    emits('getUuid',)
  }

  let fileLists = reactive([])
  let fileName = ref('拖动文件或者点击上传')
  function fileUpload(file,fileList,index){
    if(file.name){
      fileName.value = file.name
    }
    emits('fileUpload',file,fileList,index)
  }
  function uploadHttpRequest(val){
    //覆盖默认上传行为
    let file = val.file
    if(file.name){
      fileName.value = file.name
    }
    emits('fileUpload',file)
  }
  // 文件替换
  const upload = ref(null)
  const handleExceed = (uploadfiles) => {
    upload.value[0].clearFiles()
    const file = uploadfiles[0]
    file.uid = genFileId()
    upload.value[0].handleStart(file)
  }
  // 文件移除
  function handleRemove(file, uploadFiles){
    console.log(file, uploadFiles)
  }
  function beforeRemove(uploadFile, uploadFiles){
    emits('handleRemove')
  }


  let soform = ref(null)
  // 通过计算属性来验证表单
  const rules = reactive({})
  const setRules = computed(() => {
    props.element.forEach(item => {
      if(item.re == true){
        // 如果自己有验证规则
        if(item.rule){
          rules[item.key] = item.rule
        }else{
          rules[item.key] = [
          {required: true,message: item.label + "不能为空!", trigger: ['blur', 'change']}
        ]
        }
      }
    })
    return rules
  })

  function remoteMethod(val){
    console.log(val);
  }



  // 暴露属性
  defineExpose({soform,upload})

  let refrashForm = ref(true)
// 字典匹配
  function getDictLabel(data,key,type){
    if(data === undefined || data === '' || data === null || data.length == 0){
      return ''
    }
    let type2 = type ==  undefined ? "id" : type
    let labels = []
    labels = data.filter(item => item[type2] == key)
    labels = labels.map(citem => citem.label)
    return labels.join(',')
  }


  let refrashSel = ref(true)
  watch(() => props.form,() =>{
    refrashSel.val = false
    nextTick(() =>{
    refrashSel.val = true
    })
  },{
    deep:true,
  })

</script>


<style lang='scss' >
.u-common-form{
  .u-form-upload{
    width: 100%;
  }
  .el-row{
    .el-form-item{
      .el-form-item__label{
      font-weight: bold !important;
      }
    }
  }
  .el-input-number .el-input__inner{
    text-align: left !important;
  }
  .over-form-label .el-form-item__label{
    line-height: 20px !important;
  }
}
</style>
